#include <iostream>
#include <string>
#include<memory>

using namespace std;

class Car
{
public:
    Car(string name):_name(name){}
    virtual void show() = 0; //定义纯虚函数，子类必须实现

protected:
    string _name;

private:
};
class BMW:public Car
{
public:
    // 使用Car(name)类似于_name(name)，还是用了Car的_name，
    // 子类继承父类的构造函数可以参考 https://blog.csdn.net/aquapisces/article/details/104371658
    BMW(string name) : Car(name){};
    void show()
    {
        cout << "获取了一辆宝马汽车" << _name << endl;
    } 
protected : 
private:
};
class Audi : public Car
{
public:
    // 使用Car(name)类似于_name(name)，还是用了Car的_name，
    // 子类继承父类的构造函数可以参考 https://blog.csdn.net/aquapisces/article/details/104371658
    Audi(string name) : Car(name){};
    void show()
    {
        cout << "获取了一辆奥迪汽车" << _name << endl;
    }

protected:
private:
};

class Light
{
public:
    virtual void show() = 0;
};

class BMWLight:public Light
{
public:
    void show()
    {
        cout << "BMW light!" << endl;
    }
};

class AudiLight : public Light
{
public:
    void show()
    {
        cout << "Audi light!" << endl;
    }
};
// ------------------------------------------------------------------------------------------
/*
简单工厂存在以下问题：开闭原则，新增一个汽车则需要修改很多代码；BMW类和Audi类都在一个工厂里面生产
*/
enum CarType
{
    bmw,audi
};
class SimpleFactory
{
public:
    Car* createCar(CarType ct)
    {
        switch (ct)
        {
        case bmw:
            return new BMW("X1");
        case audi:
            return new Audi("A6");
        default:
            cout << "传入工厂的参数不正确：" << ct << endl;
            break;
        }
        return nullptr;
    }
};
// ------------------------------------------------------------------------------------------
/*
工厂方法
*/
class Factory
{
public:
    virtual Car* createCar(string name) = 0;
};
class BMWFactory:public Factory
{
public:
    Car* createCar(string name)
    {
        return new BMW(name);
    }
};
class AudiFactory : public Factory
{
public:
    Car *createCar(string name)
    {
        return new Audi(name);
    }
};
// ------------------------------------------------------------------------------------------


int main()
{
    // unique_ptr无法进行普通拷贝构造和赋值unique_ptr<Car> p1=new BMW("X1");是错误的
    // 最原始的对象产生
    unique_ptr<Car> p1(new BMW("X1"));
    unique_ptr<Car> p2(new Audi("A6"));

    // 简单工厂
    // unique_ptr<SimpleFactory> factory(new SimpleFactory());
    // unique_ptr<Car> p1(factory->createCar(bmw));
    // unique_ptr<Car> p2(factory->createCar(audi));

    // 工厂方法
    // unique_ptr<Factory> bmwFactory(new BMWFactory);
    // unique_ptr<Factory> audiFactory(new AudiFactory);
    // unique_ptr<Car> p1(bmwFactory->createCar("X6"));
    // unique_ptr<Car> p2(audiFactory->createCar("A8"));

    p1->show();
    p2->show();

    return 0;
}